﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using KZ400B.Data;


namespace KZ400B
{
    public delegate void PlanStepChange(int totalLoop,int step,int stepLoop); 
    public delegate void PlanComplete(bool success);
    public delegate void PlanStepException(Exception ex);
    public class TPlanManager : PropertyChangedBase
    {
        DB.BLL.TPlan m_tManager = new DB.BLL.TPlan();
        DB.BLL.TPlanAxle m_aManager = new DB.BLL.TPlanAxle();
        DB.BLL.TPlanStep m_sManager = new DB.BLL.TPlanStep();
        public List<DB.Model.TPlan> getList()
        {
            List<DB.Model.TPlan> tList = m_tManager.GetModelList(string.Empty);
            List<DB.Model.TPlanAxle> aList = m_aManager.GetModelList(string.Empty);
            List<DB.Model.TPlanStep> sList = m_sManager.GetModelList(string.Empty);
            if (tList != null)
            {
                for (int i = 0; i < tList.Count; i++)
                {
                    int tID = tList[i].ID;
                    Func<DB.Model.TPlanAxle,bool> aCdt = new Func<DB.Model.TPlanAxle,bool>(n=>n.TPlanID == tID);
                    Func<DB.Model.TPlanStep, bool> sCdt = new Func<DB.Model.TPlanStep, bool>(n => n.TPlanID == tID);
                    if (aList != null && aList.Count(aCdt) > 0)
                    {
                        tList[i].AxleList = aList.Where(aCdt).ToList<DB.Model.TPlanAxle>();
                    }
                    if (sList != null && sList.Count(sCdt) > 0)
                    {
                        tList[i].StepList = sList.Where(sCdt).ToList<DB.Model.TPlanStep>();
                    }
                }
            }
            return tList;
        }

        public List<DB.Model.TPlanAxle> getAxleList(int tID)
        {
            if (tID == 0)
            {
                return null;
            }
            string cdt = string.Format(" TPlanID = {0} ", tID);
            List<DB.Model.TPlanAxle> aList = m_aManager.GetModelList(cdt);
            return aList;
        }

        public DB.Model.TPlan getModel(int tID)
        {
            if (tID == 0)
            {
                return null;
            }
            DB.Model.TPlan tModel = m_tManager.GetModel(tID);
            string cdt = string.Format(" TPlanID = {0} ", tID);
            List<DB.Model.TPlanAxle> aList = m_aManager.GetModelList(cdt);
            List<DB.Model.TPlanStep> sList = m_sManager.GetModelList(cdt);
            if (tModel != null)
            {
      
                    //Func<DB.Model.TPlanAxle, bool> aCdt = new Func<DB.Model.TPlanAxle, bool>(n => n.TPlanID == tID);
                    //Func<DB.Model.TPlanStep, bool> sCdt = new Func<DB.Model.TPlanStep, bool>(n => n.TPlanID == tID);
                    if (aList != null )
                    {
                        tModel.AxleList = aList;
                    }
                    if (sList != null)
                    {
                        tModel.StepList = sList;
                    }
                
            }
            return tModel;
        }

        /// <summary>
        /// 删除方案
        /// </summary>
        /// <param name="tPlan"></param>
        /// <returns></returns>
        public bool delete(int tpID)
        {
            bool rst = false;
            string cdt = string.Format(" TPlanID = {0} ", tpID);
            rst = m_aManager.Delete(cdt);
             m_sManager.Delete(cdt);
             m_tManager.Delete(tpID);
            return rst;
        }

        /// <summary>
        /// 修改方案
        /// </summary>
        /// <param name="tPlan"></param>
        /// <param name="aList"></param>
        /// <returns></returns>
        public bool update(DB.Model.TPlan tPlan, List<DB.Model.TPlanAxle> aList)
        {
            if (tPlan == null) return false;
            if (m_tManager.Exists(tPlan.ID, tPlan.Name))
            {
                throw new Exception(string.Format("方案名称:[{0}] 已经存在!",tPlan.Name));
            }
            bool rst = m_tManager.Update(tPlan);
            if (rst)
            {
                string cdt = string.Format(" TPlanID = {0} ", tPlan.ID);
                List<DB.Model.TPlanAxle> oList = m_aManager.GetModelList(cdt);
                //rst = rst && m_aManager.Delete(cdt);
                if (rst && aList != null)
                {
                    foreach (DB.Model.TPlanAxle tA in aList)
                    {
                        if (tA != null)
                        {
                            tA.TPlanID = tPlan.ID;
                            //rst = rst && m_aManager.Add(tA);
                            if (oList != null && oList.Count > 0)
                            {
                                //old List exist //edit
                                if (oList.Count(n => n.TPlanID == tA.TPlanID && n.AxleID == tA.AxleID) > 0)
                                {
                                    DB.Model.TPlanAxle oM = oList.First(n => n.TPlanID == tA.TPlanID && n.AxleID == tA.AxleID);
                                    tA.ID = oM != null ? oM.ID : tA.ID;
                                    rst = rst && m_aManager.Update(tA);
                                    if (oM != null)
                                    {
                                        oList.Remove(oM);
                                    }
                                }
                                else
                                {
                                    tA.TPlanID = tPlan.ID;
                                    rst = rst && m_aManager.Add(tA);
                                }
                            }
                            else
                            {
                                tA.TPlanID = tPlan.ID;
                                rst = rst && m_aManager.Add(tA);
                            }
                           
                            
                        }
                    }
                }


                //old List exist new List not Exist
                if (oList != null && oList.Count > 0)
                {
                    foreach (DB.Model.TPlanAxle oA in oList)
                    {
                        if (oA != null)
                        {
                            rst = rst && m_aManager.Delete(oA.ID);
                            //delete tplan item
                            if (rst)
                            {
                                cdt = string.Format("TPlanAxleID = {0} ", oA.ID);
                                m_sManager.Delete(cdt);
                            }
                        }
                    }
                }
            }
            return rst;
        }

        public int add(DB.Model.TPlan tPlan, List<DB.Model.TPlanAxle> aList)
        {
            if (tPlan == null) return 0;
            if (m_tManager.Exists(tPlan.ID, tPlan.Name))
            {
                throw new Exception(string.Format("方案名称:[{0}] 已经存在!", tPlan.Name));
            }
            bool rst = m_tManager.Add(tPlan);
            if (rst && aList != null)
            {
                tPlan.ID = m_tManager.GetMaxId() - 1;
                foreach (DB.Model.TPlanAxle tA in aList)
                {
                    if (tA != null)
                    {
                        tA.TPlanID = tPlan.ID;
                        rst = rst && m_aManager.Add(tA);
                    }
                }
            }
            return rst ? tPlan.ID : 0;
        }

        /// <summary>
        /// 添加步骤
        /// </summary>
        /// <param name="step"></param>
        /// <returns></returns>
        public bool addStep(DB.Model.TPlanStep step)
        {
           return m_sManager.Add(step);
        }

        public bool updateStep(DB.Model.TPlanStep step)
        {
            return m_sManager.Update(step);
        }

        /// <summary>
        /// 移除步骤
        /// </summary>
        /// <param name="step"></param>
        /// <returns></returns>
        public bool removeStep(DB.Model.TPlanStep step)
        {
            return m_sManager.Delete(step.ID);
        }

        //public event PlanStepChange OnStepChange;
        public event PlanStepException OnException;
        Thread m_tRun = null;
        volatile bool m_isRunning = false;
        object m_prLocker = new object();
        public bool IsRunning
        {
            get
            {
                lock (m_prLocker)
                {
                    return m_isRunning;
                }
            }
        }

        void setIsRunning(bool isRunning)
        {
            lock (m_prLocker)
            {
                m_isRunning = isRunning;
            }
        }

        class RunAxleManagerV1
        {
            static bool registed = false;
            public static void Regist(string aName)
            {
                if (!string.IsNullOrEmpty(aName))
                {
                    List<string> aList = new List<string>();
                    aList.Add(aName);
                    Regist(aList);
                }

            }

            public static void Regist(List<DB.Model.TPlanAxle> axleList)
            {
                if (axleList != null)
                {
                    List<string> aList = new List<string>();
                    foreach (DB.Model.TPlanAxle a in axleList)
                    {
                        aList.Add(a.AxleName);
                    }
                    Regist(aList);
                }
                //if (axleList != null)
                //{
                //    lock (s_rgLock)
                //    {
                //        if (!registed)
                //        {
                //            AxleManager.OnAxleActionResponse += new AxleActionResponse(AxleManager_OnAxleActionResponse);
                //        }
                //        registed = true;
                //    }
                //    lock (s_tzLock)
                //    {
                //        s_tzList = new List<string>();
                //    }
                //    foreach (DB.Model.TPlanAxle a in axleList)
                //    {
                //        lock (s_tzLock)
                //        {
                //            s_tzList.Add(a.AxleName);
                //        }
                //    }
                //    lock (s_psLock)
                //    {
                //        s_psList = new List<string>(s_tzList); 
                //    }
                //}
            }

            public static void Regist(List<string> axleList)
            {
                if (axleList != null)
                {
                    lock (s_rgLock)
                    {
                        if (!registed)
                        {
                            AxleManager.OnAxleActionResponse += new AxleActionResponse(AxleManager_OnAxleActionResponse);
                        }
                        registed = true;
                    }
                    lock (s_tzLock)
                    {
                        s_tzList = new List<string>();
                    }
                    foreach (string a in axleList)
                    {
                        lock (s_tzLock)
                        {
                            s_tzList.Add(a);
                        }
                    }
                    lock (s_psLock)
                    {
                        s_psList = new List<string>(s_tzList);
                    }
                }
            }

            static void AxleManager_OnAxleActionResponse(
                string axleName
                , Axle axle
                , AxleActions action
                , bool success
                , string message)
            {
                if (action == AxleActions.ToZeroFinish)
                {
                    rmToZeroAxle(axleName);
                }
                else if (action == AxleActions.RunFinish)
                {
                    rmPsAxle(axleName);
                }
            }

            static void rmToZeroAxle(string aName)
            {
                lock (s_tzLock)
                {
                    if (s_tzList != null && s_tzList.Count > 0)
                    {
                        s_tzList.Remove(aName);
                    }
                }
            }

            static void rmPsAxle(string aName)
            {
                lock (s_psLock)
                {
                    if (s_psList != null && s_psList.Count > 0)
                    {
                        s_psList.Remove(aName);
                    }
                }
            }

            public static void UnRegist()
            {
                lock (s_rgLock)
                {
                    AxleManager.OnAxleActionResponse -= new AxleActionResponse(AxleManager_OnAxleActionResponse);
                    registed = false;
                }

                lock (s_tzLock)
                {
                    s_tzList.Clear();
                }

                lock (s_psLock)
                {
                    s_psList.Clear();
                }
            }
            static object s_rgLock = new object();
            static object s_tzLock = new object();
            static object s_psLock = new object();
            static List<string> s_tzList;
            static List<string> s_psList;

            public static bool IsToZeroReady()
            {
                lock (s_tzLock)
                {
                    if (s_tzList == null || s_tzList.Count == 0) return true;
                }

                return false;
            }

            public static bool IsPositionSettingReady()
            {
                lock (s_psLock)
                {
                    if (s_psList == null || s_psList.Count == 0) return true;
                }
                return false;
            }

        }

        class RunAxleManagerV2
        {
            static bool registed = false;
            public static void Regist(string aName)
            {
                if (!string.IsNullOrEmpty(aName))
                {
                    List<string> aList = new List<string>();
                    aList.Add(aName);
                    Regist(aList);
                }

            }

            public static void Regist(List<DB.Model.TPlanAxle> axleList)
            {
                if (axleList != null)
                {
                    List<string> aList = new List<string>();
                    foreach (DB.Model.TPlanAxle a in axleList)
                    {
                        aList.Add(a.AxleName);
                    }
                    Regist(aList);
                }
                //if (axleList != null)
                //{
                //    lock (s_rgLock)
                //    {
                //        if (!registed)
                //        {
                //            AxleManager.OnAxleActionResponse += new AxleActionResponse(AxleManager_OnAxleActionResponse);
                //        }
                //        registed = true;
                //    }
                //    lock (s_tzLock)
                //    {
                //        s_tzList = new List<string>();
                //    }
                //    foreach (DB.Model.TPlanAxle a in axleList)
                //    {
                //        lock (s_tzLock)
                //        {
                //            s_tzList.Add(a.AxleName);
                //        }
                //    }
                //    lock (s_psLock)
                //    {
                //        s_psList = new List<string>(s_tzList); 
                //    }
                //}
            }

            public static void Regist(List<string> axleList)
            {
                if (axleList != null)
                {
                    lock (s_rgLock)
                    {
                        if (!registed)
                        {
                            //AxleManager.OnAxleActionResponse += new AxleActionResponse(AxleManager_OnAxleActionResponse);
                        }
                        registed = true;
                    }
                    lock (s_tzLock)
                    {
                        s_tzList = new List<string>();
                    }
                    foreach (string a in axleList)
                    {
                        lock (s_tzLock)
                        {
                            s_tzList.Add(a);
                        }
                    }
                    lock (s_psLock)
                    {
                        s_psList = new List<string>(s_tzList);
                    }
                }
            }

            static void AxleManager_OnAxleActionResponse(
                string axleName
                , Axle axle
                , AxleActions action
                , bool success
                , string message)
            {
                if (action == AxleActions.ToZeroFinish)
                {
                    rmToZeroAxle(axleName);
                }
                else if (action == AxleActions.RunFinish)
                {
                    rmPsAxle(axleName);
                }
            }

            static void rmToZeroAxle(string aName)
            {
                lock (s_tzLock)
                {
                    if (s_tzList != null && s_tzList.Count > 0)
                    {
                        s_tzList.Remove(aName);
                    }
                }
            }

            static void rmPsAxle(string aName)
            {
                lock (s_psLock)
                {
                    if (s_psList != null && s_psList.Count > 0)
                    {
                        s_psList.Remove(aName);
                    }
                }
            }

            public static void UnRegist()
            {
                lock (s_rgLock)
                {
                    AxleManager.OnAxleActionResponse -= new AxleActionResponse(AxleManager_OnAxleActionResponse);
                    registed = false;
                }

                lock (s_tzLock)
                {
                    s_tzList.Clear();
                }

                lock (s_psLock)
                {
                    s_psList.Clear();
                }
            }
            static object s_rgLock = new object();
            static object s_tzLock = new object();
            static object s_psLock = new object();
            static List<string> s_tzList;
            static List<string> s_psList;

            public static bool IsToZeroError()
            {
                lock (s_tzLock)
                {
                    if (s_tzList == null || s_tzList.Count == 0) return false;
                    else
                    {
                        bool rst = false;
                        foreach (string an in s_tzList)
                        {
                            if (AxleCacheManager.AxleList.ContainsKey(an))
                            {
                                rst |= AxleCacheManager.AxleList[an].OtherAxleStatus == AxleActions.ToZeroError;
                                if (rst) return true;
                            }
                        }
                        return rst;
                    }
                }
            }

            public static bool IsToZeroReady()
            {
                lock (s_tzLock)
                {
                    if (s_tzList == null || s_tzList.Count == 0) return true;
                    else
                    {
                        bool rst = true;
                        foreach (string an in s_tzList)
                        {
                            if (AxleCacheManager.AxleList.ContainsKey(an))
                            {
                                rst &= (AxleCacheManager.AxleList[an].AxleStatus == AxleStatus.Stoped
                                    && AxleCacheManager.AxleList[an].OtherAxleStatus == AxleActions.ToZeroFinish
                                    )
                                        
                                    ;
                                if (!rst) return false;
                            }
                        }
                        return rst;
                    }
                }

                //return false;
            }

            public static bool IsPositionSettingError()
            {
                lock (s_psLock)
                {
                    if (s_psList == null || s_psList.Count == 0) return false;
                    else
                    {
                        bool rst = false;
                        foreach (string an in s_tzList)
                        {
                            if (AxleCacheManager.AxleList.ContainsKey(an))
                            {
                                rst |= AxleCacheManager.AxleList[an].OtherAxleStatus == AxleActions.RunError;
                                if (rst) return true ;
                            }
                        }
                        return rst;
                    }
                }
                //return true;
            }

            public static bool IsPositionSettingReady()
            {
                lock (s_psLock)
                {
                    if (s_psList == null || s_psList.Count == 0) return true;
                    else
                    {
                        bool rst = true;
                        foreach (string an in s_tzList)
                        {
                            if (AxleCacheManager.AxleList.ContainsKey(an))
                            {
                                rst &= (AxleCacheManager.AxleList[an].AxleStatus == AxleStatus.Stoped
                                    && AxleCacheManager.AxleList[an].OtherAxleStatus == AxleActions.RunFinish
                                    )
                                    ;
                                if (!rst) return false;
                            }
                        }
                        return rst;
                    }
                }
            }

        }

        void setStepChange(int totalLoop, int step, int stepLoop)
        { 
            //if (OnStepChange != null)
            //{
            //    OnStepChange(totalLoop, step, stepLoop);
            //}
            TotalLoop = totalLoop;
            SubStep = step;
            SubStepLoop = stepLoop;
        }

        void setException(Exception ex)
        {
            AxleStateBarMsg.Instance.AxleState = ex.Message;
            if (OnException != null)
            {
                OnException(ex);
            }
        }


        int m_TotalLoop;

        public int TotalLoop
        {
            get { return m_TotalLoop; }
            set { if (m_TotalLoop != value) { m_TotalLoop = value; this.NotifyPropertyChanged(n => n.TotalLoop); } }
        }
        int m_SubStep;

        public int SubStep
        {
            get { return m_SubStep; }
            set
            {
                if (m_SubStep != value) { m_SubStep = value;
                this.NotifyPropertyChanged(n => n.SubStep);
                }
            }
        }
        int m_SubStepLoop;

        public int SubStepLoop
        {
            get { return m_SubStepLoop; }
            set { if (m_SubStepLoop != value) { m_SubStepLoop = value;
            this.NotifyPropertyChanged(n => n.SubStepLoop);
            } }
        }
        
         void setState(string state)
        {
            Data.AxleStateBarMsg.Instance.AxleState = state;
        }

         bool runToPosition(DB.Model.TPlan plan,bool toZero)
         { 
            if (plan == null || TPRStateManager.Instance[plan.ID] == null) return false;

            bool onExp = false;
            List<DB.Model.TPlanAxle> axleList = plan.AxleList;

            RunAxleManagerV2.Regist(axleList);
            //to zero
            if (toZero 
                && TPRStateManager.Instance[plan.ID].Process == TPRProcess.NotBegin)
            {
                if (axleList != null && axleList.Count > 0)
                {
                    foreach (DB.Model.TPlanAxle pA in axleList)
                    {
                        AxleManager.ToZeroIM(pA.AxleName
                            , AxleCacheManager.AxleList[pA.AxleName].getTozeroPwm(
                            AxleCacheManager.AxleList[pA.AxleName].TozeroSpeed
                            ));
                    }
                }
                TPRStateManager.Instance[plan.ID].setState(TPRProcess.BeginToZero);
            }

            //run to start position
            List<DB.Model.TPlanAxle> rList = new List<DB.Model.TPlanAxle>();
            if (axleList != null && axleList.Count > 0 
                && TPRStateManager.Instance[plan.ID].Process != TPRProcess.NotBegin
            )
            {
                bool pmSetRst = true;
                foreach (DB.Model.TPlanAxle pA in axleList)
                {
                    if (TPRStateManager.Instance[plan.ID].getToZeroState(pA.AxleName))
                    {
                        rList.Add(pA);
                        continue;
                    }

                    Axle ax = AxleCacheManager.getAxle(pA.AxleName);
                    double totalStep = 0.0F;
                    int direct = Axle.Direction.ForwardDirection.Value;
                    totalStep = ax.ComputeAddtion(pA.StartPosition ?? 0.0F, ref direct);
                    if (totalStep == 0.0F) continue;
                    Axle.Direction dirt = new Axle.Direction(direct);
                    ax.Addtion = totalStep;
                    double pwm = ax.getRunPwm(ax.RunSpeed);

                    try
                    {
                        
                        pmSetRst &= AxleManager.ParameterSetting(pA.AxleName
                            , dirt
                            , pwm
                            , ax.TotalStep
                            );
                        TPRStateManager.Instance[plan.ID].setToZeroState(pA.AxleName, pmSetRst);
                        if (!pmSetRst)
                        {
                            setState(
                                string.Format("{0}轴参数设置错误,方案退出运行", pA.AxleName)
                                );
                            onExp = true;
                            setIsRunning(false);
                            break;
                        }
                        else { rList.Add(pA); }

                    }
                    catch (Exception ex)
                    {
                        //if (OnException != null)
                        //{
                        //    OnException(ex);
                        //}
                        setException(ex);
                        onExp = true; break;
                    }
                }
                if (pmSetRst)
                {
                    foreach (DB.Model.TPlanAxle pA in rList)
                    {
                        if (TPRStateManager.Instance[plan.ID][pA.AxleName])
                        {
                            continue;
                        }
                        onExp = !AxleManager.RunIM(pA.AxleName);
                        //Thread.Sleep(100);
                        if (onExp)
                        {
                            setState(string.Format("[{0}]轴运行到位置[{1}]时出现错误!", pA.AxleName, pA.StartPosition ?? 0));
                            break;
                        }
                        else
                        {
                            TPRStateManager.Instance[plan.ID][pA.AxleName] = true;
                        }
                    }
                }
                if (toZero)
                {
                    TPRStateManager.Instance[plan.ID].setState(TPRProcess.BeginToStartPosition);
                }
                else
                {
                    TPRStateManager.Instance[plan.ID].setState(TPRProcess.EndToStartPosition);
                }
            }
             return !onExp ;//&& ! isTO;
         }
         public event PlanComplete OnPlanCompleted;
        private void doRun(object arg)
        {
            bool isCompleted = false;
            if (!AxleManager.IsOpen) return;
            if (IsRunning) return;
            //setStepChange(0, 0, 0);
            bool runRst = false;
            if (arg == null) return;
            setIsRunning(true);
            int tID = Convert.ToInt32(arg);
            DB.Model.TPlan plan = getModel(tID);
            bool onExp = false;


            try// setIsRunning(false);
            {
                if (plan == null || TPRStateManager.Instance[plan.ID] == null)
                {
                    setIsRunning(false);
                    return;
                }
                if (TPRStateManager.Instance[plan.ID].Process == TPRProcess.NotBegin)
                {
                    setStepChange(0, 0, 0);
                }
                    List<DB.Model.TPlanAxle> axleList = plan.AxleList;
                    if (axleList != null)
                    {
                        List<string> aList = new List<string>();
                        foreach (DB.Model.TPlanAxle ax in axleList)
                        {
                            aList.Add(ax.AxleName);
                        }
                        TPRStateManager.Instance[plan.ID].setAxleList(aList);
                    }

                    if (TPRStateManager.Instance[plan.ID].Process == TPRProcess.NotBegin
                        || TPRStateManager.Instance[plan.ID].NoInitReady
                        )
                    {
                        onExp = !runToPosition(plan, true);
                    }

                    int iTLoop = TPRStateManager.Instance[plan.ID].TotalStep;
                    int stepIdx = TPRStateManager.Instance[tID].InnerStep;
                    int stepLoopIdx = TPRStateManager.Instance[tID].InnerStepLoop;
                    //if (iTLoop != 0 || stepIdx != 0 || stepLoopIdx != 0)
                    //{
                    //    setStepChange(iTLoop + 1, stepIdx + 1, stepLoopIdx + 1);
                    //}
                    //for (int iTLoop = 0; !onExp && IsRunning && iTLoop < plan.LoopTimes; iTLoop++)
                    for (;
                        !onExp && IsRunning && iTLoop < plan.LoopTimes
                        && (TPRStateManager.Instance[tID].Process == TPRProcess.BeginToStartPosition
                            || TPRStateManager.Instance[tID].Process == TPRProcess.Executing);
                        iTLoop++)
                    {
                        //setStepChange(iTLoop + 1, stepIdx + 1,stepLoopIdx + 1);
                        //setStepChange(iTLoop , stepIdx , stepLoopIdx );
                        TPRStateManager.Instance[tID].setState( iTLoop, stepIdx, stepLoopIdx);
                        List<DB.Model.TPlanStep> stepList = plan.StepList;
                        if (stepList != null && stepList.Count > 0)
                        {
                            //int stepIdx = 0;
                            //foreach (DB.Model.TPlanStep step in stepList)
                            for (;
                                !onExp && IsRunning && stepIdx < plan.StepList.Count
                                && TPRStateManager.Instance[tID].Process == TPRProcess.Executing;
                            stepIdx++)
                            {
                                DB.Model.TPlanStep step = stepList[stepIdx];
                                if (!IsRunning)
                                {
                                    break;
                                }
                                DB.Model.TPlanAxle tAx = m_aManager.GetModel(step.TPlanAxleID);
                                if (tAx == null) { onExp = true; break; }
                                Axle ax = AxleCacheManager.getAxle(tAx.AxleName);
                                if (ax == null) { onExp = true; break; }

                                ax.Addtion = Math.Abs(step.RunDistance);
                                if (ax.TotalStep == 0.0F) continue;
                                ax.RunSpeed = step.RunSpeed;
                                try
                                {
                                    AxleManager.ParameterSetting(tAx.AxleName
                                     , step.RunDistance > 0
                                         ? Axle.Direction.ForwardDirection
                                         : Axle.Direction.BackDirection
                                     , ax.RunPWM
                                     , ax.TotalStep
                                     );
                                }
                                catch (Exception ex)
                                {
                                    //if (OnException != null)
                                    //{
                                    //    OnException(ex);
                                    //}
                                    setException(ex);
                                    onExp = true; break;
                                }
                                //if (OnStepChange != null)
                                //{
                                //    OnStepChange(iTLoop + 1, stepIdx + 1,  1);
                                //}
                                //setStepChange(iTLoop + 1, stepIdx + 1, 1);
                                //TPRStateManager.Instance[tID].setState(iTLoop, stepIdx, 0);
                                //setStepChange(iTLoop + 1, stepIdx + 1, stepLoopIdx + 1);
                                //setStepChange(iTLoop , stepIdx , stepLoopIdx );
                                //TPRStateManager.Instance[tID].setState(iTLoop, stepIdx, stepLoopIdx);

                                
                                for (;
                                    !onExp && IsRunning && stepLoopIdx < step.StepLoopTimes
                                    && TPRStateManager.Instance[tID].Process == TPRProcess.Executing
                                    ; stepLoopIdx++)
                                {
                                    //if (OnStepChange != null)
                                    //{
                                    //    OnStepChange(iTLoop + 1, stepIdx + 1, stepLoopIdx + 1);
                                    //}
                                    //setStepChange(iTLoop + 1, stepIdx + 1, stepLoopIdx + 1);
                                    //TPRStateManager.Instance[tID].setState(iTLoop, stepIdx, stepLoopIdx);
                                    //==//setStepChange(iTLoop + 1, stepIdx + 1, stepLoopIdx + 1);
                                    //TPRStateManager.Instance[tID].setState(iTLoop, stepIdx, stepLoopIdx);
                                    if (!IsRunning)
                                    {
                                        break;
                                    }
                                    int delay = step.Delay;
                                    //while (delay > 0)
                                    //{
                                    //    Thread.Sleep(100);
                                    //    delay -= 100;
                                    //}
                                    Thread.Sleep(delay);
                                    try
                                    {
                                        //RunAxleManagerV2.Regist(ax.Name);

                                        
                                        runRst = AxleManager.RunIM(ax.Name);
                                        if (runRst)
                                        {
                                            setStepChange(iTLoop + 1, stepIdx + 1, stepLoopIdx + 1);
                                            TPRStateManager.Instance[tID].setState(iTLoop, stepIdx, stepLoopIdx+1);
                                        }
                                        //RunAxleManagerV2.UnRegist();
                                        //AxleManager.QueryPosition(ax.Name);
                                    }
                                    catch (Exception exr)
                                    {
                                        //if (OnException != null)
                                        //{
                                        //    OnException(exr);
                                        //}
                                        setException(exr);
                                        onExp = true; break;
                                    }
                                    if (!IsRunning || onExp)
                                    {
                                        break;
                                    }
                                    //need wait for run success
                                }
                                stepLoopIdx = 0;
                                //stepIdx++;
                                //if (OnStepChange != null)
                                //{
                                //    OnStepChange(iTLoop + 1, stepIdx + 1, 1);
                                //}
                            }//execute step
                            stepIdx = 0;
                        }//step list count > 0
                    }

                    //back to start position
                    if (!onExp && IsRunning)
                    {
                        if (TPRStateManager.Instance[tID].Process != TPRProcess.NotBegin
                            || TPRStateManager.Instance[plan.ID].NoToPositionReady
                            )
                        {
                            runToPosition(plan, false);
                        }
                    }
                    

                //}//plan != null

                    if (IsRunning)
                    {
                        //TPRStateManager.Instance[tID].setState(TPRProcess.NotBegin);
                        setState("方案运行结束!");
                        isCompleted = true;
                        TPRStateManager.Instance[tID].Reset();
                    }
                    else
                    {
                        setState("方案运行暂停!");
                    }
            }//try->setIsRunning(false);
            finally { setIsRunning(false);
            }

            
            setIsRunning(false);
            if (isCompleted && OnPlanCompleted != null)
            {
                OnPlanCompleted(!onExp);
            }
        }
        /// <summary>
        /// 自定义运行
        /// </summary>
        /// <param name="tID"></param>
        public void Run(int tID)
        {
            if (IsRunning) return;
            m_tRun = new Thread(new ParameterizedThreadStart(doRun));
            m_tRun.Priority = ThreadPriority.BelowNormal;
            m_tRun.Start(tID);
        }

        public void Stop(int tID)
        {
            Thread.CurrentThread.Priority = ThreadPriority.Highest;
            if (AxleCacheManager.AxleList != null)
            {
                foreach (string ax in AxleCacheManager.AxleList.Keys)
                {
                    if (ax != null)
                    {
                        if (AxleCacheManager.AxleList[ax].AxleStatus != AxleStatus.Stoped)
                        {
                            AxleManager.Stop(ax);
                            AxleCacheManager.AxleList[ax].AxleStatus = AxleStatus.Stoped;
                        }
                    }
                }
            }
            setIsRunning(false);
            try
            {
                if (m_tRun != null)
                {
                    m_tRun = null;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

    }
}
